package com.codemeta.bokit.security.config;

import cn.dev33.satoken.interceptor.SaAnnotationInterceptor;
import cn.dev33.satoken.interceptor.SaRouteInterceptor;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.strategy.SaStrategy;
import com.codemeta.bokit.props.SecurityProps;
import com.codemeta.bokit.security.vars.SecurityVars;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * sa-token-web自动装配
 *
 * @author hice
 * @date 2021/11/19
 */
@Slf4j
@Configuration
@AllArgsConstructor
public class SaTokenSecurityWebAutoConfig implements WebMvcConfigurer {

    private final SecurityProps props;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 打开Sa-Token注解式鉴权
        registry.addInterceptor(new SaAnnotationInterceptor()).addPathPatterns("/**");
        // 注册Sa-Token路由拦截器
        registry.addInterceptor(new SaRouteInterceptor((req, res, handler) -> {
            // 登录认证 -- 拦截所有路由，并排除whitelist白名单
            SaRouter.match("/**")
                .notMatch(SecurityVars.STATICS)
                .notMatch(props.getWhitelist())
                .check(r -> StpUtil.checkLogin());
        })).addPathPatterns("/**");
        log.debug("【bokit】注册Sa-Token 的拦截器，打开注解式鉴权功能");
    }

    /**
     * 重写 Sa-Token 框架内部算法策略
     */
    @Autowired
    public void rewriteSaStrategy() {
        // 重写Sa-Token的注解处理器，增加注解合并功能
        SaStrategy.me.getAnnotation = AnnotatedElementUtils::getMergedAnnotation;
    }

}